<?php

include "fun.php";
pcntl_signal(SIGINT, 'sigProcess');


$connect_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (false === $connect_sock) {
    echo "socket_create err:" . print_r(socket_last_error(), 1);
    exit();
}
$bind_res = socket_bind($connect_sock, HOST, PORT);
if (false === $bind_res) {
    echo "socket_bind err:" . print_r(socket_last_error(), 1);
    exit();
}

$listen = socket_listen($connect_sock);
if (false === $listen) {
    echo "socket_listen err:" . print_r(socket_last_error(), 1);
    exit();
}
socket_set_nonblock($connect_sock);
echo "listen sock======" . HOST . ":" . PORT . "#########" . intval($connect_sock) . PHP_EOL;
//被监听的

$connect_id = intval($connect_sock);
$clients = [$connect_id => $connect_sock];


while (true) {
    pcntl_signal_dispatch();
    $read = $clients;
    if (($change = @socket_select($read, $write, $except, NULL)) > 0) {
        echo "change:" . socktonum($read) . PHP_EOL;

        //查看连接sock是否在变动的里面,如果在说明是连接行为
        if (in_array($connect_sock, $read)) {
            //从变动的里面读出客户端socket
            $sock_client = socket_accept($connect_sock);
            //获取连接的客户端的ip和端口
            if (socket_getpeername($sock_client, $clinet_addr, $client_port)) {
                echo " [new client:" . intval($sock_client) . " from  {$clinet_addr}:$client_port]";
                sayWelcome($sock_client);
            }
            $clients[intval($sock_client)] = $sock_client; //加入到客户端连接集合
            unset($read[$connect_id]);//这个连接sock已处理，下面处理 会话sock
        }
        //处理会话连接(非新连接接入的sock)
        if (count($read) > 0) {
            //逐个读取
            foreach ($read as $k => $client_sock) {
                $len = socket_recv($client_sock, $buf, 10, MSG_DONTWAIT);
                if (!$len) {
                    socket_close($client_sock);
                    unset($clients[$k]);
                    continue;
                }

                echo date("H:i:s") . " read " . $len . ",content:{" . $buf . '}';
                //收到客户端退出请求
                if ($buf == 'quit') {
                    unset($clients[intval($client_sock)]);
                    socket_shutdown($client_sock);
                }
                foreach ($clients as $client) {
                    //不给自己和 连接sock发
                    if ($client == $connect_sock || $client == $client_sock) {
                        continue;
                    }
                    $send = "from " . $k . ":" . $buf . "\n";
                    socket_write($client, $buf, strlen($send));
                }
            }
        }
        echo PHP_EOL . "被监听的io:" . socktonum($clients) . PHP_EOL;

    } else {
        echo PHP_EOL . "被监听的socket未发生变动" . PHP_EOL;
    }
}










